package com.woniuxy.merchant.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniu.dto.BusinessHoursDto;
import com.woniu.dto.SiteDto;
import com.woniu.dto.SiteListDto;
import com.woniu.form.AddSiteForm;
import com.woniu.form.SiteListForm;
import com.woniu.form.UpdateSiteForm;
import com.woniu.zsd.commons.core.exception.ZsdException;
import com.woniu.zsd.commons.core.model.Result;
import com.woniu.zsd.merchant.client.PermissionClient;
import com.woniuxy.merchant.entity.Site;
import com.woniuxy.merchant.mapper.SiteMapper;
import com.woniuxy.merchant.service.ISiteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 站点信息表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-05-13
 */
@Service
public class SiteServiceImpl extends ServiceImpl<SiteMapper, Site> implements ISiteService {

    @Resource
    private SiteMapper siteMapper;
    @Resource
    private PermissionClient permissionClient;
    @Autowired
    private ObjectMapper objectMapper;
    /**
     * 判断是否在同一位置（1000米范围内）存在同名站点
     */
    private boolean isSameLocation(String siteName, double longitude, double latitude) {
        List<Site> sites = siteMapper.selectList(
                new QueryWrapper<Site>().eq("site_name", siteName).eq("is_delet", 1));

        for (Site s : sites) {
            double dist = calcDistance(latitude, longitude, s.getLatitude(), s.getLongitude());
            if (dist <= 1000) return true;
        }
        return false;
    }

    /**
     * 计算两个经纬度点之间的距离（单位：米）
     */
    private double calcDistance(double lat1, double lon1, double lat2, double lon2) {
        double R = 6371000; // 地球半径，单位：米
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(dLon / 2) * Math.sin(dLon / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return R * c;
    }
    @Override
    public void addSite(AddSiteForm addSiteForm) {
        if (isSameLocation(addSiteForm.getSiteName(), addSiteForm.getLongitude(), addSiteForm.getLatitude())) {
            throw new ZsdException("附近位置已存在站点",500);
        }

        Site site = new Site();
        site.setSiteName(addSiteForm.getSiteName());
        site.setSiteAddress(addSiteForm.getSiteAddress());
        site.setLongitude(addSiteForm.getLongitude());
        site.setLatitude(addSiteForm.getLatitude());
        site.setBusinessHours(JSONUtil.toJsonStr(addSiteForm.getBusinessHours()));
        site.setSiteUserPhone(addSiteForm.getSiteUserPhone());
        site.setSiteDesc(addSiteForm.getSiteDesc());
        site.setCity(addSiteForm.getCity());
        site.setDistrict(addSiteForm.getDistrict());
        site.setStatus(1);
        site.setUserId(addSiteForm.getUserId());
        site.setIsDelet(1);
        site.setCreatTime(LocalDateTime.now());
        siteMapper.insert(site);
    }

    @Override
    public void deleteSite(Integer siteId) {
        QueryWrapper<Site> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", siteId);
        Site site = siteMapper.selectOne(queryWrapper);
        if (site == null) throw new ZsdException("不存在该站点", 500);
        Site site1 = new Site();
        site1.setIsDelet(0);
        site1.setStatus(0);
        siteMapper.update(site1, queryWrapper);
    }

    @Override
    public void updateSite(UpdateSiteForm updateSiteForm, Integer id) {
        QueryWrapper<Site> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        Site site = siteMapper.selectOne(queryWrapper);
        if (site == null) throw new ZsdException("不存在该站点", 500);
        Site site1 = new Site();
        site1.setSiteName(updateSiteForm.getSiteName());
        site1.setSiteUserPhone(updateSiteForm.getSiteUserPhone());
        site1.setUserName(updateSiteForm.getSiteUserName());
        site1.setSiteDesc(updateSiteForm.getSiteDesc());
        siteMapper.updateById(site1);

    }

    @Override
    public Page<SiteListDto> siteList(SiteListForm siteListForm) {
        Page<Site> page = new Page<>(siteListForm.getPageNum() == null ? 1 : siteListForm.getPageNum(),
                siteListForm.getPageSize() == null ? 5 : siteListForm.getPageSize());
        QueryWrapper<Site> queryWrapper = new QueryWrapper<>();

        if (siteListForm.getStatus() != null) {
            queryWrapper.eq("status", siteListForm.getStatus());
        }

        if (siteListForm.getName() != null && !siteListForm.getName().isEmpty()) {
            queryWrapper.like("site_name", siteListForm.getName());
        }

        if (siteListForm.getCity() != null && !siteListForm.getCity().isEmpty()){
            queryWrapper.eq("city", siteListForm.getCity());
        }

        if (siteListForm.getDistrict() != null && !siteListForm.getDistrict().isEmpty()){
            queryWrapper.eq("district", siteListForm.getDistrict());
        }

        Page<Site> sitePage = siteMapper.selectPage(page, queryWrapper); // 假设这里没有额外的查询条件

        return (Page<SiteListDto>) sitePage.convert(site -> {
            SiteListDto siteListDto = new SiteListDto();
            BeanUtils.copyProperties(site, siteListDto);

            // 将 businessHours 字符串转换为 List<BusinessHoursDto>
            try {
                if (site.getBusinessHours() != null && !site.getBusinessHours().equals("")){
                    List<BusinessHoursDto> businessHoursList = objectMapper.readValue(site.getBusinessHours(), objectMapper.getTypeFactory().constructCollectionType(List.class, BusinessHoursDto.class));
                    siteListDto.setBusinessHours(businessHoursList);
                }
            } catch (IOException e) {
                throw new RuntimeException("Failed to convert businessHours to List<BusinessHoursDto>", e);
            }

            return siteListDto;
        });
    }

    @Override
    public List<SiteListDto> getSiteByMerchantId(Integer merchantId) {
        QueryWrapper<Site> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", merchantId);
        List<Site> sites = siteMapper.selectList(wrapper);
        if (sites == null)throw new ZsdException("没有查询到数据", 500);
        // 转成 DTO 列表
        List<SiteListDto> dtoList = sites.stream()
                .map(site -> BeanUtil.copyProperties(site, SiteListDto.class))
                .collect(Collectors.toList());
        return dtoList;
    }

    /**
     * 查询出未被删除的站点
     *过滤出5公里以内的站点，并通过calcDistance方法按距离排序
     * @param longitude
     * @param latitude
     * @return
     */
    @Override
    public List<Site> recentSiteId(Double longitude, Double latitude) {
        List<Site> siteList = siteMapper.selectList( new LambdaQueryWrapper<Site>()
                .eq(Site::getIsDelet, 0)
        );
        // 2. 计算每个站点与目标坐标的距离
        // 用于存放符合条件的站点
        List<Site> resultList = new ArrayList<>();

        // 遍历每一个站点
        for (Site site : siteList) {

            // 获取当前站点的经纬度
            double siteLatitude = site.getLatitude();
            double siteLongitude = site.getLongitude();

            // 计算与目标坐标的距离
            double distance = calcDistance(latitude, longitude, siteLatitude, siteLongitude);

            // 判断是否在 5 公里范围内
            if (distance <= 5.0) {
                // 满足条件的站点加入结果列表
                resultList.add(site);
            }
        }
        return resultList;

    }

    @Override
    public SiteDto siteId(Integer siteId) {
        Site site = siteMapper.selectById(siteId);
        if (site == null) {
            throw new ZsdException("没有此站点", 500);
        }
        SiteDto siteDto = new SiteDto();
        BeanUtils.copyProperties(site, siteDto);
        return siteDto;
    }
}
